﻿package bdz.projects.lavender.opsm.model {
	import bdz.projects.lavender.opsm.events.FlipModelEvent;
	import bdz.projects.lavender.opsm.vo.ProductVO;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	/**
	 * ...
	 * @author Donald
	 */
	public dynamic class FlipCollection extends Array implements IEventDispatcher {
		private var _source:XML;
		private var dispatcher:EventDispatcher;
		private var _cache:Array = new Array();
		private var _delayDispatch:Boolean = false;
		public function FlipCollection() {
			super();	
			
			dispatcher = new EventDispatcher(this);	
		}
		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
			dispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
			dispatcher.removeEventListener(type, listener, useCapture);
		}
		public function dispatchEvent(event:Event):Boolean {
			return dispatcher.dispatchEvent(event);	
		}
		public function hasEventListener(type:String):Boolean {
			return dispatcher.hasEventListener(type);
		}
		public function willTrigger(type:String):Boolean {
			return dispatcher.willTrigger(type);
		}
		private function clear():void {
			if(length){
				for each(var pvo:ProductVO in this) {
					pvo.clear();
					pvo = null;
				}
				while (length) {
					shift();
				}
			}
		}
		private function applyValues():void {
			var xlist:XMLList = _source.product;
			var counter:Number = 0;
			for each(var xm:XML in xlist) {
				var pvo:ProductVO = new ProductVO(xm);
				pvo.index = counter;
				push(pvo);
				counter++;
			}
			if(!_delayDispatch){
				dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_CHANGED, this));
			}
			
		}
		public function executeDelayedDispatch():void {
			_delayDispatch = false;
			dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_CHANGED, this));
		}
		public function parseXML(xm:XML, delay:Boolean = false ):void {
			_delayDispatch = delay;
			_source = xm;
			clear();
			applyValues();
		}
		public function getProductsWithID(id:String):Array {
			var ret:Array = new Array();
			var copy:Array = this.slice();
			for each(var pvo:ProductVO in copy) {
				if (pvo.productID == id) {
					ret.push(pvo);
				}
			}
			return ret;
		}
		public function getProductWithSKU(id:String):ProductVO {
			for each(var pvo:ProductVO in this) {
				if (pvo.sku == id) {
					return pvo;
				}
			}
			return null;
		}
		public function applyFilterSet(arr:Array):void {
			for each(var obj:Object in arr){
				var i:int = -1;
				var indices:Array = new Array();
				while (++i < length) {
					var pvo:ProductVO = this[i];
					if (pvo.isTypeOf(obj.title, obj.type)) {
						indices.push(i);
					}
				}
			}
			if (indices.length) {
				for each(var ii:int in indices) {
					_cache.push({index:ii, value:this.splice(ii, 1)[0]});
				}
			}
			if (length) {
				dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_FILTERED, this));
			}
		}
		public function applyFilter(title:String, type:String):void {
			var i:int = -1;
			var indices:Array = new Array();
			while (++i < length) {
				var pvo:ProductVO = this[i];
				if (pvo.isTypeOf(title, type)) {
					indices.push(i);
				}
			}
			if (indices.length) {
				for each(var ii:int in indices) {
					_cache.push({index:ii, value:this.splice(ii, 1)[0]});
				}
			}
			if (length) {
				dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_FILTERED, this));
			}
		}
		public function sortByDate():void {
			this.sortOn("time", Array.DESCENDING);
			dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_FILTERED, this));
		}
		public function sortByPrice(sorttype:String):void {
			this.sortOn("price", sorttype == "desc" ? Array.DESCENDING : null);
			dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_FILTERED, this));
		}
		public function clearFilters():void {
			for each(var o:Object in _cache) {
				this.splice(o.index, 0, o.value);
			}
			dispatchEvent(new FlipModelEvent(FlipModelEvent.COLLECTION_FILTER_CLEARED, this));
		}
	}
	
}